/*
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package jdk.io;

import java.util.*;
import java.io.File;

/**
 * 此类持有一组文件名，在虚拟机退出时通过关闭钩子删除。
 * 使用集合来防止同一文件重复插入以及提供快速删除。
 */

class DeleteOnExitHook {
    private static LinkedHashSet<String> files = new LinkedHashSet<>();
    static {
        // DeleteOnExitHook必须是最后被调用的关闭钩子。
        // 应用程序关闭钩子可能会将第一个文件添加到
        // 退出时删除列表中，并导致DeleteOnExitHook在关闭进行中时
        // 被注册。因此将registerShutdownInProgress参数设置为true。
        sun.misc.SharedSecrets.getJavaLangAccess()
            .registerShutdownHook(2 /* 关闭钩子调用顺序 */,
                true /* 即使关闭进行中也要注册 */,
                new Runnable() {
                    public void run() {
                       runHooks();
                    }
                }
        );
    }

    private DeleteOnExitHook() {}

    static synchronized void add(String file) {
        if(files == null) {
            // DeleteOnExitHook正在运行。添加文件太晚了
            throw new IllegalStateException("关闭正在进行中");
        }

        files.add(file);
    }

    static void runHooks() {
        LinkedHashSet<String> theFiles;

        synchronized (DeleteOnExitHook.class) {
            theFiles = files;
            files = null;
        }

        ArrayList<String> toBeDeleted = new ArrayList<>(theFiles);

        // 反转列表以保持之前jdk的删除顺序。
        // 最后添加的最先删除。
        Collections.reverse(toBeDeleted);
        for (String filename : toBeDeleted) {
            (new File(filename)).delete();
        }
    }
}
